use std::cmp::Ordering;
use std::fmt::{Debug, Display, Formatter};
use std::mem;
use std::mem::MaybeUninit;
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::ptr::NonNull;
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;

use hierarchical_hash_wheel_timer::wheels::quad_wheel::QuadWheelWithOverflow;
use hierarchical_hash_wheel_timer::{TimerEntry, UuidOnlyTimerEntry};
use lazy_static::lazy_static;

use crate::utils::thread_pool::time_cost_once;

pub mod multi_cond;
pub mod ptr_model;
pub mod thread_pool;
pub mod cache_model;

pub use ptr_model::*;
pub type DynFn = dyn Fn() -> () + Send + 'static;
pub type DynFnOnce = dyn FnOnce() -> () + Send + 'static;
pub type DynFnMut = dyn FnMut() -> () + Send + 'static;

//快排找中点
fn quick_sort_partition<T: Ord>(slice: &mut [T], ord: Ordering) -> usize {
    let end = slice.len() - 1;
    let mut mid = 0;
    for i in 0..end {
        if slice[i].cmp(&slice[end]) == ord {
            slice.swap(i, mid);
            mid += 1;
        }
    }
    slice.swap(end, mid);
    mid
}

pub fn quick_sort<T>(slice: &mut [T], ord: Ordering)
where
    T: Ord,
{
    if !slice.is_empty() {
        let len = slice.len();
        let mid = quick_sort_partition(slice, ord);
        quick_sort(&mut slice[0..mid], ord);
        quick_sort(&mut slice[mid + 1..len], ord);
    }
}

#[macro_export]
macro_rules! box_fn {
    ($func:expr) => {
        Box::new($func) as Box<DynFn>
    };
}

#[macro_export]
macro_rules! box_fn_mut {
    ($func:expr) => {
        Box::new($func) as Box<DynFnMut>
    };
}

#[macro_export]
macro_rules! box_fn_once {
    ($func:expr) => {
        Box::new($func) as Box<DynFnOnce>
    };
}
// 和mem::write不同，=会自动drop原有的变量，write不会触发此操作
#[macro_export]
macro_rules! unsafe_assign {
    ($e:expr,$val:expr) => {
        unsafe {
            *(&$e as *const _ as *mut _) = $val;
        }
    };
}
///用于获取变量的可变引用
#[macro_export]
macro_rules! to_mut_ref {
    ($e:expr,$t:ty) => {
        unsafe {
            &mut *($e as *const _ as *mut $t)
        }
    };
}
/// # Example
/// 方便的固定一个数据
/// pin可以固定栈空间和堆空间的数据，防止移动的时候内部数据的地址被改变
/// box通常只能在堆空间上分配，如果面对函数的地址处理会有额外的分配开销
/// 使用案例，
/// 1.
/// ```
/// safe_pin!{
///     let msg = "test_str".to_string();
/// }
/// let mut_msg = msg.as_mut();
/// ```
/// 2.
///  ```
/// let code = "is right space".to_string();
/// safe_pin!(code);
/// //后续的code都是pin, 把之前的给shadow了，可以始终保证，
/// //即使是在栈空间上其所有权的变量生命周期依旧是安全的
/// let mut_code = code.as_mut();
///
///  ```
#[macro_export]
macro_rules! safe_pin {
    ($($x:ident),*) => { $(
        // Move the value to ensure that it is owned
        let mut $x = $x;
        // Shadow the original binding so that it can't be directly accessed
        // ever again.
        #[allow(unused_mut)]
        let mut $x = unsafe {
            $crate::Pin::new_unchecked(&mut $x)
        };
    )* };
    ($(
            let $x:ident = $init:expr;
    )*) => {
        $(
            let $x = $init;
            $crate::safe_pin!($x);
        )*
    };
}
/// 用法同safe_pin!
#[macro_export]
macro_rules! thread_safe_ptr {
    ($($x:ident),*) => { $(
        let $x = $x;
        let mut $x = unsafe {
            $crate::utils::ThreadSafePtr::capture(& $x)
        };
    )* };
    ($(
            let $x:ident = $init:expr;
    )*) => {
        $(
            let $x = $init;
            $crate::thread_safe_ptr!($x);
        )*
    };
}

#[macro_export]
macro_rules! thread_safe_slice {
    ($($x:ident),*) => { $(
        let $x = $x;
        let mut $x = unsafe {
            $crate::utils::ThreadSafePtr::capture_slice($x)
        };
    )* };
    ($(
            let $x:ident = $init:expr;
    )*) => {
        $(
            let $x = $init;
            $crate::thread_safe_slice!($x);
        )*
    };
}
#[test]
fn tt() {
    safe_pin! {
        let msg = "asd".to_string();
    }
    println!("{:?}", msg);
    let x1 = msg.get_mut();
    *x1 = "ok".to_owned();
    println!("{:?}", x1);
}
#[test]
fn thread_safe() {
    let option = Some(1);
    thread_safe_ptr! {
        let a = 1;
    }
    let x = a;
    let x1 = x.deref();
    println!("{x1}")
}
#[test]
fn thread_safe_some() {
    thread_safe_ptr! {
        let a = Some(1);
    }
    a.read_write_ops(|e| {
        println!("{e}");
        Some(12)
    });
    println!("{a:?}");
}
